/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package persistencia;

import Dominio.Calificacion;
import Dominio.Especialidad;
import Dominio.Usuario;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Agustin
 */
public class PersistenciaUsuario {

    private static PersistenciaUsuario instance;

    public static PersistenciaUsuario getInstance() {
        if (instance == null) {
            instance = new PersistenciaUsuario();
        }
        return instance;
    }

    public ResultSet ejecutarSeleccion(String query) throws SQLException {
        ResultSet rs;
        try {
            Conexion.getInstance().conectar();
            rs = Conexion.getInstance().select(query);
        } catch (Exception e) {
            throw new UnsupportedOperationException(e.toString());
        }
        return rs;
    }

    public Usuario recorerRS(ResultSet rs, int x) throws SQLException, ParseException {
        Usuario u1 = new Usuario();
        try {
            SimpleDateFormat formato = new SimpleDateFormat("dd-MM-yyyy");
            SimpleDateFormat formatoAux = new SimpleDateFormat("yyyy-MM-dd");
            u1.setNombre_usuario(rs.getObject(1).toString());
            u1.setContraseña(rs.getObject(2).toString());
            String fecha = rs.getObject(4).toString();
            u1.setFecha_inscripcion(formato.parse(fecha));

            int experienciaExtra = Integer.parseInt(rs.getObject(8).toString());
            Date fechaActual = new Date();
            String fechaActualS = formatoAux.format(fechaActual);
            String[] fechaActual1 = fechaActualS.split("-");
            Integer anioHoy = Integer.parseInt(fechaActual1[0]);
            String xx = "";
            boolean b = true;
            for (char c : fecha.toCharArray()) {
                if (b) {
                    if (c == ' ') {
                        b = false;
                    } else {
                        xx += "" + c;
                    }
                }
            }
            String[] fechaAnt = xx.split("-");
            Integer anioAnt = Integer.parseInt(fechaAnt[0]);
            u1.setExperiencia((anioHoy - anioAnt) + experienciaExtra);
            u1.setExperienciaEx(experienciaExtra);
            u1.setActivo(true);
            u1.setNombre(rs.getObject(6).toString());
            Especialidad esp = new Especialidad();
            esp = esp.traerEspecialidades(rs.getObject(7).toString()).get(0);
            u1.setEspecialidad(esp);
            Calificacion c = new Calificacion();
            u1.setCalificaciones(c.traerCalificaciones(u1.getNombre_usuario()));
            String aux = rs.getObject(5).toString().trim();
            if (!aux.equals("true") && !aux.equals("false")) {
                u1.setVHU(Double.parseDouble(aux));
            }
            if (x == 1) {
                update(u1.getNombre_usuario(), u1.getContraseña(), u1.getExperiencia(), u1.getExperienciaEx(), u1.getNombre(), u1.getEspecialidad().getNombre());
            }
        } catch (Exception e) {
            throw new UnsupportedOperationException(e.toString());
        }


        return u1;
    }

    public List<Usuario> traerRS(String query, int x) throws ParseException, SQLException {
        List<Usuario> usuarios = new ArrayList<Usuario>();
        try {
            ResultSet rs = ejecutarSeleccion(query);
            if (rs.next()) {
                usuarios.add(recorerRS(rs, x));
                while (rs.next()) {
                    usuarios.add(recorerRS(rs, x));
                }
            } else {
                Usuario u = new Usuario();
                usuarios.add(u);
            }
        } catch (SQLException ex) {
            Logger.getLogger(PersistenciaUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }
        Conexion.getInstance().desconectar();
        return usuarios;
    }

    public List<Usuario> select(String nombre_usuario) throws ParseException, SQLException {
        String query = "";
        int x = 0;
        if (nombre_usuario.equals("")) {
            query = "select * from Usuarios where activo=true order by nombre_usuario";
        } else if (!nombre_usuario.equals("")) {
            query = "select * from Usuarios where activo=true and nombre_usuario='" + nombre_usuario + "'";
        } else if (nombre_usuario.equals("act")) {
            query = "select * from Usuarios where activo=true order by nombre_usuario";
            x = 1;
        }
        return traerRS(query, x);
    }

    public List<Usuario> selectEmpleados(int rut, int t) throws ParseException, SQLException {
        String query = "";
        if (t == 0) {
            //empleados
            query = "select Usuarios.nombre_usuario,Usuarios.contrasenia,Usuarios.experiencia,Usuarios.fecha_inscripcion,Usuarios.activo,Usuarios.nombre,Usuarios.especialidad,usuarios.experienciaExtra from (select * from Usuarios inner join Usuarios_Empresas on Usuarios.nombre_usuario=Usuarios_Empresas.nombre_usuario where fecha_egreso is null and rut=" + rut + " order by usuarios.nombre asc ,usuarios.nombre_usuario asc)";
        } else if (t == 1) {
            //no empleados
            query = "select * from usuarios where nombre_usuario not in(select Usuarios.nombre_usuario from (select * from Usuarios inner join Usuarios_Empresas on Usuarios.nombre_usuario=Usuarios_Empresas.nombre_usuario where  Usuarios_Empresas.rut=" + rut + " and Usuarios_Empresas.fecha_egreso is null))";
        } else if (t == 2) {
            //mas calificado
            query = "select top 1 * from (select  Usuarios.nombre_usuario,Usuarios.contrasenia,Usuarios.experiencia,Usuarios.fecha_inscripcion,Usuarios.activo,Usuarios.nombre,Usuarios.especialidad, usuarios.experienciaExtra from usuarios inner join (select usuarios_empresas.nombre_usuario,count(calificaciones.valor) as calificaciones  from calificaciones inner join usuarios_empresas on calificaciones.id_empleado=usuarios_empresas.id_empleado group by nombre_usuario order by count(calificaciones.valor) desc) as tabla2 on usuarios.nombre_usuario=tabla2.nombre_usuario order by  tabla2.calificaciones desc, format (usuarios.fecha_inscripcion,'dd/MM/yyyy'))";
        }
        return traerRS(query, 2);
    }

    public List<Usuario> selectUsuarioMasCotizado() throws ParseException, SQLException {
        String query = " select top 1 * from (select DISTINCT usuarios.nombre_usuario, usuarios.contrasenia, usuarios.experiencia,usuarios.fecha_inscripcion,Especialidades.VHB*(1+0.2*experiencia+0.05*0) AS VHU,usuarios.nombre,usuarios.especialidad,usuarios.experienciaExtra from usuarios inner join especialidades on usuarios.especialidad=especialidades.nombre union select tabla2.nombre_usuario,tabla2.contrasenia,tabla2.experiencia,tabla2.fecha_inscripcion, (Especialidades.VHB*(1+0.2*experiencia+0.05*calificacion)) AS VHU, tabla2.nombre,tabla2.especialidad,tabla2.experienciaExtra from especialidades inner join (select usuarios.nombre_usuario,usuarios.contrasenia,usuarios.experiencia,usuarios.fecha_inscripcion,usuarios.nombre,usuarios.especialidad,tabla1.calificacion,usuarios.experienciaExtra from usuarios inner join (select usuarios_empresas.nombre_usuario, sum(calificaciones.valor) as calificacion from usuarios_empresas inner join calificaciones on calificaciones.id_empleado=usuarios_empresas.id_empleado group by usuarios_empresas.nombre_usuario) as tabla1 on tabla1.nombre_usuario=usuarios.nombre_usuario) as tabla2 on tabla2.especialidad=especialidades.nombre ) as tabla3 order by vhu desc , fecha_inscripcion asc";
        return traerRS(query, 2);
    }

    public List<Usuario> selectSujerenciasAContratar(String especialidad, int vhu, int rut) throws ParseException, SQLException {
        String query = "SELECT TOP 10 * FROM (select  usuarios.nombre_usuario, usuarios.contrasenia, usuarios.experiencia,usuarios.fecha_inscripcion,(Especialidades.VHB*(1+0.2*experiencia+0.05*0)) as VHU,usuarios.nombre,usuarios.especialidad,usuarios.experienciaExtra from usuarios inner join especialidades on usuarios.especialidad=especialidades.nombre where usuarios.nombre_usuario not in (select tabla2.nombre_usuario from especialidades inner join (select usuarios.nombre_usuario,usuarios.contrasenia,usuarios.experiencia,usuarios.fecha_inscripcion,usuarios.nombre,usuarios.especialidad,tabla1.calificacion from usuarios inner join (select usuarios_empresas.nombre_usuario, sum(calificaciones.valor) as calificacion from usuarios_empresas inner join calificaciones on calificaciones.id_empleado=usuarios_empresas.id_empleado group by usuarios_empresas.nombre_usuario) as tabla1 on tabla1.nombre_usuario=usuarios.nombre_usuario) as tabla2 on tabla2.especialidad=especialidades.nombre )  union    select tabla2.nombre_usuario,tabla2.contrasenia,tabla2.experiencia,tabla2.fecha_inscripcion,(iif(Especialidades.VHB*(1+0.2*experiencia+0.05*calificacion)>especialidades.vhb, Especialidades.VHB*(1+0.2*experiencia+0.05*calificacion),especialidades.vhb  ) ) AS VHU, tabla2.nombre,tabla2.especialidad, tabla2.experienciaExtra from especialidades inner join (select usuarios.nombre_usuario,usuarios.contrasenia,usuarios.experiencia,usuarios.fecha_inscripcion,usuarios.nombre,usuarios.especialidad,tabla1.calificacion, usuarios.experienciaExtra from usuarios inner join (select usuarios_empresas.nombre_usuario, sum(calificaciones.valor) as calificacion from usuarios_empresas inner join calificaciones on calificaciones.id_empleado=usuarios_empresas.id_empleado group by usuarios_empresas.nombre_usuario) as tabla1 on tabla1.nombre_usuario=usuarios.nombre_usuario) as tabla2 on tabla2.especialidad=especialidades.nombre  )  AS tabla3 WHERE tabla3.nombre_usuario not in (select Usuarios.nombre_usuario from (select * from Usuarios inner join Usuarios_Empresas on Usuarios.nombre_usuario=Usuarios_Empresas.nombre_usuario where  Usuarios_Empresas.rut=" + rut + " and Usuarios_Empresas.fecha_egreso is null)) and VHU<=" + vhu + " and especialidad='" + especialidad + "' ORDER BY vhu DESC , fecha_inscripcion, experiencia DESC;";
        return traerRS(query, 2);
    }

    public List<Usuario> selectContactos(String nombre_usuario) throws ParseException, SQLException {
        String query = "select * from Usuarios where nombre_usuario in (select nombre_usuario_contacto from Contactos_Usuarios where nombre_usuario='" + nombre_usuario + "')";
        return traerRS(query, 2);
    }

    public List<Usuario> selectSujerencias(String nombre_usuario, String especialidad) throws ParseException, SQLException {
        String query = "select * from Usuarios where nombre_usuario in (select nombre_usuario_contacto from Contactos_Usuarios where nombre_usuario in (select nombre_usuario_contacto from Contactos_Usuarios where nombre_usuario='" + nombre_usuario + "') ) and especialidad ='" + especialidad + "' and nombre_usuario not in (select nombre_usuario_contacto from Contactos_Usuarios where nombre_usuario='" + nombre_usuario + "') and nombre_usuario not in('" + nombre_usuario + "') ";
        return traerRS(query, 2);
    }

    public void insert(String nombre_usuario, String contraseña, int experiencia, Date fecha_inicio, boolean activo, String nombre, String especialidad) throws ParseException {
        try {
            SimpleDateFormat formato = new SimpleDateFormat("dd-MM-yyyy");
            String query = "";
            query = "insert into Usuarios (nombre_usuario, contrasenia,experiencia,fecha_inscripcion,activo,nombre,especialidad,experienciaExtra) values('" + nombre_usuario + "','" + contraseña + "'," + 0 + ",#" + formato.format(fecha_inicio) + "#," + activo + ",'" + nombre + "','" + especialidad + "'," + experiencia + ")";
            Conexion.getInstance().conectar();
            Conexion.getInstance().insert(query);
        } catch (SQLException ex) {
            Logger.getLogger(PersistenciaUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void insertContactos(String nombre_usuario, String nombre_usuario_contacto) throws ParseException {
        try {
            String query = "insert into Contactos_Usuarios (nombre_usuario, nombre_usuario_contacto) values('" + nombre_usuario + "','" + nombre_usuario_contacto + "')";
            String query1 = "insert into Contactos_Usuarios (nombre_usuario, nombre_usuario_contacto) values('" + nombre_usuario_contacto + "','" + nombre_usuario + "')";
            Conexion.getInstance().conectar();
            Conexion.getInstance().insert(query);
            Conexion.getInstance().insert(query1);
        } catch (SQLException ex) {
            Logger.getLogger(PersistenciaUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void update(String nombre_usuario, String contraseña, int experiencia, int experienciaExtra, String nombre, String especialidad) {
        try {
            String query = "";
            if (nombre_usuario.equals("")) {
                query = " UPDATE usuarios SET usuarios.experiencia = DateDiff('yyyy',fecha_inscripcion,Date()) + usuarios.experienciaExtra";
            } else {
                query = "update Usuarios set contrasenia='" + contraseña + "',nombre='" + nombre + "',especialidad='" + especialidad + "',experiencia=" + experiencia + ", experienciaExtra=" + experienciaExtra + " where nombre_usuario='" + nombre_usuario + "'";
            }
            Conexion.getInstance().conectar();
            Conexion.getInstance().insert(query);
        } catch (SQLException ex) {
            Logger.getLogger(PersistenciaUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void baja(String nombre_usuario) {
        try {
            String query = "delete * from Usuarios where nombre_usuario='" + nombre_usuario + "'";
            Conexion.getInstance().conectar();
            Conexion.getInstance().insert(query);
        } catch (SQLException ex) {
            Logger.getLogger(PersistenciaUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void dejarEmpresa(String nombre_usuario, int rut) {
        try {
            SimpleDateFormat formato = new SimpleDateFormat("dd-MM-yyyy");
            Date fecha_egreso = new Date();
            System.out.println(formato.format(fecha_egreso));
            String query = "update Usuarios_Empresas set fecha_egreso=#" + formato.format(fecha_egreso) + "# where rut=" + rut + " and nombre_usuario='" + nombre_usuario + "'";
            Conexion.getInstance().conectar();
            Conexion.getInstance().insert(query);
        } catch (SQLException ex) {
            Logger.getLogger(PersistenciaUsuario.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
